import mine from "@/mount/global/misson/mine"
import { isInArray, unzipPosition, zipPosition } from "@/utils"

/* 矿物相关任务  外矿、内矿 */
export default class MineMissonExtension extends Room {
    /* 房间内矿资源采集发布任务 */
    public Task_monitorMineral():void{
        if (Game.time % 67) return
        if(this.controller.level < 6) return
        if (!this.memory.StructureIdData.mineralID) return
        if (this.MissonNum('Creep','原矿开采') > 0) return
        var mineral = Game.getObjectById(this.memory.StructureIdData.mineralID) as Mineral
        if (!mineral || mineral.ticksToRegeneration) return
        if (!this.memory.mineralType) this.memory.mineralType = mineral.mineralType
        if (this.controller.level >= 6 && !this.memory.StructureIdData.extractID)
        {
            /* 寻找矿物点 在其附近撒下建筑 */
            if (!mineral.pos.GetStructure('extractor') && mineral.pos.lookFor(LOOK_CONSTRUCTION_SITES).length <= 0)
            {
                mineral.pos.createConstructionSite('extractor')
                return
            }
            return
        }
        /* 寻找mineralContainerID */
        var container_ = mineral.pos.findInRange(FIND_STRUCTURES,1,{filter:(stru)=>{
            return stru.structureType == 'container'
        }})
        var container_cons = mineral.pos.findInRange(FIND_MY_CONSTRUCTION_SITES,1,{filter:(stru)=>{
            return stru.structureType == 'container'
        }})
        if (container_.length <= 0 && container_cons.length<=0)
        {
            /* 建立container */
            var result:RoomPosition[] = []
            var terrain = new Room.Terrain(this.name)
            var xs = [mineral.pos.x-1,mineral.pos.x,mineral.pos.x+1]
            var ys = [mineral.pos.y-1,mineral.pos.y,mineral.pos.y+1]
            xs.forEach(
                x=>ys.forEach(
                    y=>{
                        if (terrain.get(x,y) != TERRAIN_MASK_WALL)
                        {
                            result.push(new RoomPosition(x,y,this.name))
                        }
                    }
                )
            )
            result[0].createConstructionSite('container')     
            return   
        }
        if (container_.length <= 0)
        {
            return
        }
        /* 建筑都到位了，开始下任务 */
        var storage_ = Game.getObjectById(this.memory.StructureIdData.storageID) as StructureStorage
        if (!storage_) return
        /* 如果矿物饱和，挂任务卖原矿 */
        if (storage_.store.getUsedCapacity(this.memory.mineralType) > 200000)
        {
            if (!this.memory.market) this.memory.market = {}
            if (!this.memory.market['deal']) this.memory.market['deal'] = []
            var bR = true
            for (var od of this.memory.market['deal'])
            {
                if (od.rType == this.memory.mineralType)
                bR = false
            }
            if (bR){
                /* 下达自动deal的任务 */
                this.memory.market['deal'].push({rType:this.memory.mineralType,num:30000})
            }
        }
        /* 防止挖矿致死 */
        if (storage_.store.getFreeCapacity() > 200000 && storage_.store.getUsedCapacity(this.memory.mineralType) < 200000)
        {
            // 下达挖矿任务
            var thisTask:MissionModel = {
                name:'原矿开采',
                range:'Creep',
                delayTick:50000,
                level:10,
                data:{
                },
            }
            thisTask.CreepBind = {'mineral':{num:1,bind:[]}}
            this.AddMisson(thisTask)
        }
    }
    /* 房间内矿资源采集任务 */
    public Task_Mineral(misson:MissionModel):void{
        if (Game.time % 68) return
        global.CreepNumData[this.name]['mineral'].num = 1
        var mineral = Game.getObjectById(this.memory.StructureIdData.mineralID) as Mineral
        if (!mineral.mineralAmount)
            this.DeleteMisson(misson.id)
    }

    /* 过道采集任务监控 */
    public Task_CrossHarvest(misson:MissionModel):void{
        if (!misson.data.time) misson.data.time = Game.time
        if (this.controller.level < 8 || !this.memory.StructureIdData.ObserverID) return
        var observer_ = Game.getObjectById(this.memory.StructureIdData.ObserverID) as StructureObserver
        if (!observer_) {delete this.memory.StructureIdData.ObserverID;return}
        if (!misson.data.relateRooms) misson.data.relateRooms = []
        if (misson.data.relateRooms.length <= 0) return
        // 房间列表索引
        if (!misson.data.index) misson.data.index = 0
        if (!misson.data.state) misson.data.state = 1
        if (misson.data.index >= misson.data.relateRooms.length){misson.data.index = 0}
        if (misson.data.state == 1)
        {
            /* 如果power和deposit都没激活就不观察 */
            if (!misson.data.power && !misson.data.deposit) return
            misson.data.time = Game.time
            /* 观察房间 */
            observer_.observeRoom(misson.data.relateRooms[misson.data.index])
            /* 获取上个tick的房间名 */
            let beforRoom:string
            if (misson.data.relateRooms.length == 1) beforRoom = misson.data.relateRooms[0]
            else if (misson.data.relateRooms.length > 1)
            {
                if (misson.data.index == 0) beforRoom = misson.data.relateRooms[misson.data.relateRooms.length -1]
                else beforRoom = misson.data.relateRooms[misson.data.index -1]
            }
            //if (this.name == 'E49S44') console.log(beforRoom)
            if (Game.rooms[beforRoom])
            {
                /* 查找power和deposit */
                if (misson.data.power)
                {

                    // if (this.MissonNum('Creep','power采集') > 0) return
                    //if (this.name == 'E49S44') console.log(beforRoom,'--')
                    var powerbank = Game.rooms[beforRoom].find(FIND_STRUCTURES,{filter:(stru)=>{
                        return stru.structureType == 'powerBank' && stru.ticksToDecay >= 3600 && stru.power > 3000
                    }}) as StructurePowerBank[]
                    
                    if (powerbank.length > 0)
                    {
                        //if (this.name == 'E49S44') console.log(beforRoom,'++')
                        let BR = true
                        for (var i of this.memory.Misson['Creep'])
                        {
                            if (i.name == 'power采集' && i.data.room == beforRoom && i.data.x == powerbank[0].pos.x && i.data.y == powerbank[0].pos.y)
                            {
                                BR = false
                            }
                        }
                        if (BR)
                        {
                            /* 下达采集任务 */
                            
                            var thisTask = this.public_PowerHarvest(beforRoom,powerbank[0].pos.x,powerbank[0].pos.y,powerbank[0].power)
                            if (thisTask != null)
                            {
                                this.AddMisson(thisTask)
                            }
                        }
                    }
                }
                if (misson.data.deposit)
                {
                    var deposit = Game.rooms[beforRoom].find(FIND_DEPOSITS,{filter:(stru)=>{
                        return  stru.ticksToDecay >= 3800  && stru.lastCooldown < 150
                    }})
                    if (deposit.length > 0)
                    {
                        let BR = true
                        for (var i of this.memory.Misson['Creep'])
                        {
                            if (i.name == 'deposit采集' && i.data.room == beforRoom && i.data.x == deposit[0].pos.x && i.data.y == deposit[0].pos.y)
                            {
                                BR = false
                            }
                        }
                        if (BR)
                        {
                            /* 下达采集任务 */
                            var thisTask = this.public_DepositHarvest(beforRoom,deposit[0].pos.x,deposit[0].pos.y,deposit[0].depositType)
                            if (thisTask != null)
                            {
                                this.AddMisson(thisTask)
                            }
                        }  
                    }
                }
            }
            misson.data.index ++
            if (Game.rooms[beforRoom] && misson.data.index == 1)
            {
                misson.data.state = 2
            }         
        }
        else if (misson.data.state == 2)
        {
            if ( (Game.time-misson.data.time) % 10) return
            /* 爬虫数量控制 */
            if (!this.memory.Misson['Creep']) this.memory.Misson['Creep'] = []
            for (var miss of this.memory.Misson['Creep'])
            {
                if (miss.CreepBind)
                for (var role in miss.CreepBind)
                for (var cName of miss.CreepBind[role].bind)
                {
                    if (Game.creeps[cName])
                    {
                        if (Object.keys(Game.creeps[cName].memory.MissonData).length <= 0)
                        {
                            var index = miss.CreepBind[role].bind.indexOf(cName)
                            miss.CreepBind[role].bind.splice(index,1)
                        }
                    }
                }
                if (miss.name == 'power采集')
                {
                    if (miss.data.state == 1)
                    {
                        miss.CreepBind['power-carry'].num = 0
                        global.CreepNumData[this.name]['power-attack'].num += miss.CreepBind['power-attack'].num
                        global.CreepNumData[this.name]['power-heal'].num += miss.CreepBind['power-heal'].num
                    }
                    else if (miss.data.state == 2)
                    {
                        if (!miss.data.down) miss.data.down = false
                        if (!miss.data.down)
                        {
                            miss.CreepBind['power-carry'].num = Math.ceil(miss.data.num/1600)
                            miss.data.down = true
                        }
                        global.CreepNumData[this.name]['power-carry'].num += miss.CreepBind['power-carry'].num
                        miss.CreepBind['power-attack'].num = 0
                        miss.CreepBind['power-heal'].num = 0
                        if (miss.CreepBind['power-carry'].num == miss.CreepBind['power-carry'].bind.length)
                        {
                            miss.CreepBind['power-carry'].num = 0
                        }
                        if (miss.CreepBind['power-attack'].bind.length <= 0 && miss.CreepBind['power-heal'].bind.length <= 0 && miss.CreepBind['power-carry'].bind.length <= 0)
                        {
                            //if (Game.time % 1135)
                            this.DeleteMisson(miss.id)
                        }

                    }
                }
                if (miss.name == 'deposit采集')
                {
                    global.CreepNumData[this.name]['deposit'].num += 1
                }

            }
            if (Game.time - misson.data.time != 0 && (Game.time-misson.data.time) % 60 == 0)
                misson.data.state = 1
        }

    }

    /* 烧Power发布函数任务 */
    public Task_montitorPower():void{
        if (Game.time % 7) return
        if (this.controller.level < 8) return
        if (!this.memory.StopPower) this.memory.StopPower = false
        if (!this.memory.StopPower) return
        // 有任务了就不发布烧帕瓦的任务
        if (this.MissonNum('Structure','power升级') > 0) return
        let storage_ = global.Stru[this.name]['storage'] as StructureStorage
        //  powerspawn_ = global.Stru[this.name]['powerspawn'] as StructurePowerSpawn
        if (!storage_) return
        if (storage_.store.getUsedCapacity('energy') > 40000 && storage_.store.getUsedCapacity('power') > 1000)
        {
            /* 发布烧power任务 */
            var thisTask:MissionModel = {
                name:'power升级',
                delayTick:200,
                range:'Structure',
                state:1
            }
            this.AddMisson(thisTask)
        }
    }

    /* 烧Power执行函数 */
    public Task_ProcessPower(misson:MissionModel):void{
        let storage_ = global.Stru[this.name]['storage'] as StructureStorage
        let powerspawn_ = global.Stru[this.name]['powerspawn'] as StructurePowerSpawn
        let terminal_ = global.Stru[this.name]['terminal'] as StructureTerminal
        if (!storage_ || !powerspawn_ || !terminal_)return
        if (misson.state == 1)
        {
            if (storage_.store.getUsedCapacity('power') + terminal_.store.getUsedCapacity('power') < 5000)
            {
                this.Deal_Resource('power',5000,40,100)
            }
            if (powerspawn_.store.getFreeCapacity('energy') > 0)
            {
                var carryTask = this.Public_Carry({'manage':{num:1,bind:[]}},10,this.name,storage_.pos.x,storage_.pos.y,this.name,powerspawn_.pos.x,powerspawn_.pos.y,'energy',powerspawn_.store.getFreeCapacity('energy'))
                this.AddMisson(carryTask)
                return
            }
            if (powerspawn_.store.getFreeCapacity('power') > 0)
            {
                var carryTask = this.Public_Carry({'manage':{num:1,bind:[]}},10,this.name,storage_.pos.x,storage_.pos.y,this.name,powerspawn_.pos.x,powerspawn_.pos.y,'power',powerspawn_.store.getFreeCapacity('energy'))
                this.AddMisson(carryTask)
                return
            }
            misson.state = 2

        }
        else if (misson.state == 2)
        {
            powerspawn_.processPower()
            if (powerspawn_.store.getUsedCapacity('energy') == 0 || powerspawn_.store.getUsedCapacity('power') == 0)
                this.DeleteMisson(misson.id)
        }
    }

    /* 外矿任务执行函数 */
    public Task_OutMine(misson:MissionModel):void{
        if (!misson.data.time) misson.data.time = Game.time
        if (Game.time % 13) return
        // 默认是1阶段
        if (!misson.data.state) misson.data.state = 1
        global.CreepNumData[this.name]['out-claim'].num += 1   // 无论什么阶段claim都会默认生产
        var disRoomName = misson.data.disRoom
        misson.CreepBind['out-claim'].num = 1
        if (!Memory.outMineData) Memory.outMineData = {}
        if (!Memory.outMineData[disRoomName]) Memory.outMineData[disRoomName] = {road:[],startpoint:misson.data.startpoint,minepoint:[],}
        if (Memory.outMineData[disRoomName].minepoint && Memory.outMineData[disRoomName].minepoint.length > 0)
        {
            for (var obj of Memory.outMineData[disRoomName].minepoint)
            {
                if (obj.bind && obj.bind.harvest && !Game.creeps[obj.bind.harvest]) delete obj.bind.harvest
                if (obj.bind && obj.bind.car && !Game.creeps[obj.bind.car]) delete obj.bind.car
            }
        }
        if (misson.data.state == 1)
        {
            /* 状态1下仅仅获取外矿信息和派出claimer */
            if (Game.rooms[disRoomName])
            {
                var sources = Game.rooms[disRoomName].find(FIND_SOURCES)
                if (sources.length <= 0)
                {
                    console.log(`房间${disRoomName}未发现能量点！删除外矿任务！`)
                    this.DeleteMisson(misson.id)
                    return
                }
                /* 说明有该房间的视野了 先查找矿点 */
                if (Memory.outMineData[disRoomName].minepoint.length < sources.length)
                {
                    LoopS:
                    for (var s of sources)
                    {
                        for (var m of Memory.outMineData[disRoomName].minepoint)
                        {
                            if (m.pos == zipPosition(s.pos))
                                continue LoopS
                        }
                        Memory.outMineData[disRoomName].minepoint.push({pos:zipPosition(s.pos),bind:{}})
                    }
                    return
                }
                /* 矿点信息更新完毕了 接下来更新路线信息 */
                if (!misson.data.roadUpdated)
                {
                    var startpos = unzipPosition(Memory.outMineData[disRoomName].startpoint)
                    if (!startpos) {console.log(`${startpos}不能解压成RoomPosition对象`);return}
                    /* 每个矿点都要有一个路线信息 */
                    for (var s of sources)
                    {
                        var results = startpos.FindPath(s.pos,2)
                        LoopB:
                        for (var p of results)
                        {
                            if (isInArray([0,49],p.x) || isInArray([0,49],p.y)) continue LoopB
                            /* 如果不再路径点缓存中，就push进路径列表中 */
                            if (!isInArray(Memory.outMineData[disRoomName].road,zipPosition(p)))
                            {
                                Memory.outMineData[disRoomName].road.push(zipPosition(p))
                            }
                        }
                    }
                    misson.data.roadUpdated = true
                    return
                }
                /* 路线信息更新完毕 接下来进入阶段2 */
                /* 先看路径点中是否有本房间的位置点，有的话就创建工地 */
                for (var mess of Memory.outMineData[disRoomName].road)
                {
                    if (unzipPosition(mess).roomName == this.name)
                    {
                        unzipPosition(mess).createConstructionSite('road')
                        //var index = Memory.outMineData[disRoomName].road.indexOf(mess)
                        //Memory.outMineData[disRoomName].road.splice(index,1)
                    }
                }
                misson.data.state = 2
            }
        }
        else if (misson.data.state == 2)
        {
            /* 状态2下正常采集 */
            global.CreepNumData[this.name]['out-harvest'].num += Memory.outMineData[disRoomName].minepoint.length
            misson.CreepBind['out-harvest'].num = Memory.outMineData[disRoomName].minepoint.length
            if (Memory.outMineData[disRoomName].car)
            {
                global.CreepNumData[this.name]['out-car'].num += Memory.outMineData[disRoomName].minepoint.length
                misson.CreepBind['out-car'].num = Memory.outMineData[disRoomName].minepoint.length
            }
            else misson.CreepBind['out-car'].num = 0
            misson.CreepBind['out-defend'].num = 0
        }
        else if (misson.data.state == 3)
        {
            /* 状态3下实施外矿防御，孵化防御爬虫 */
            
            misson.CreepBind['out-claim'].num = 0
            misson.CreepBind['out-harvest'].num = 0
            misson.CreepBind['out-car'].num = 0
            global.CreepNumData[this.name]['out-defend'].num += 2
            misson.CreepBind['out-defend'].num = 2
            if (Game.rooms[misson.data.disRoom])
            {
                var enemys = Game.rooms[misson.data.disRoom].find(FIND_HOSTILE_CREEPS,{filter:(creep)=>{
                    return !isInArray(Memory.whitesheets,creep.owner.username)
                }})
                var InvaderCore = Game.rooms[misson.data.disRoom].find(FIND_STRUCTURES,{filter:(stru)=>{
                    return stru.structureType == STRUCTURE_INVADER_CORE
                }})
                if (enemys.length <=0 && InvaderCore.length <= 0)
                    misson.data.state = 2
            }
        }
    }
}